package netty.simple.heartBeat;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName MyServer
 * @Description TODO
 * @Author director吴
 * @Date 2022/4/8 14:16
 * @Version 1.0
 **/
public class MyServer {

    public static void main(String[] args) throws Exception {

        NioEventLoopGroup bossGroup = new NioEventLoopGroup(1);
        NioEventLoopGroup workGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap();

            bootstrap.group(bossGroup,workGroup)
                    .channel(NioServerSocketChannel.class)
                    .handler(new LoggingHandler(LogLevel.INFO)) //在bossgroup中 添加日志处理器（netty自带的）
                    .childHandler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            //加入netty提供的  IdlestateHandler 处理器

                            /**
                             *  readerIdleTime 表示 一个时间内（），服务器没有读操作（服务端-接收-客户端的消息） 就会发送心跳包
                             *  writerIdleTime,表示 一个时间范围内（），服务器没有写操作（服务端-发送消息-客户端） 就会发送心跳包
                             *  allIdleTime,表示 一个时间范围内（），服务器没有读、写操作 就会发送心跳包
                             *
                             * 文档说明：
                             *  * Triggers an {@link IdleStateEvent} when a {@link Channel} has not performed
                             *  * read, write, or both operation for a while.
                             *  * 长时间没有读、写、或者读写操作，就会触发IdleStateEvent事件
                             *  * 当IdleStateHandler处理器出发了事件，会交给下一个处理器处理
                             *
                             */

                            //当触发事件后， 处理器一  --->  将触发的事件 交给我们自定义的处理器二 处理
                            //处理器一
                            pipeline.addLast(new IdleStateHandler(3, 5, 7, TimeUnit.SECONDS));
                            //处理器二
                            pipeline.addLast(new MyServerHandler());
                        }
                    });


            ChannelFuture channelFuture = bootstrap.bind(7000).sync();
            channelFuture.channel().closeFuture().sync();


        }finally {
            bossGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
        }

    }
}
